#pragma once

namespace _hHuffmanDetail
{
	struct Node;

	struct CodeCallback
	{
		hBitStr& _outData;
		const char* _inDt = NULL;
		size_t _len = 0;
		Node* _pTree = NULL;
		std::map<uint8_t, size_t> _charTab;
		std::map<uint8_t, hBitStr> _keyTab;
		std::multimap<size_t, Node*> _freqTab;

		void operator() ();

	private:
		void init();
		void show();
		void fin();
		void code();
		void showCharTab() const;
		void showKeyTab() const;
		void showTree() const;
		void showBit() const;

		void genKeyTabCb(const Node* pTree, hBitStr val);
		void codeTreeCb(const Node* pTree);
		void finCb(const Node* pTree);
	};

	struct DecodeCallback
	{
		const hBitStr& _inBit;
		hBitView _view{ _inBit };
		size_t _len = 0;
		Node* _pTree = NULL;

		template <typename T>
		void operator() (T& outDt);

	private:
		void init();
		void show();
		void fin();
		void decode(std::string& outDt);

		void genTreeCb(Node*& pTree);
		void finCb(const Node* pTree);
	};
}